package thoven.achievement.net.jsonutil.service

import com.google.gson.GsonBuilder
import com.google.gson.JsonParser
import com.google.gson.JsonSyntaxException

/**
 * JSON 格式化服务
 */
object JsonFormatter {
    
    private val prettyGson = GsonBuilder()
        .setPrettyPrinting()
        .serializeNulls()
        .disableHtmlEscaping()
        .create()
    
    private val compactGson = GsonBuilder()
        .serializeNulls()
        .disableHtmlEscaping()
        .create()
    
    /**
     * 格式化 JSON 字符串
     */
    fun format(json: String, indent: Int = 2): Result<String> {
        return try {
            val jsonElement = JsonParser.parseString(json)
            val formatted = prettyGson.toJson(jsonElement)
            
            // 如果需要自定义缩进，则调整
            if (indent != 2) {
                Result.success(adjustIndent(formatted, indent))
            } else {
                Result.success(formatted)
            }
        } catch (e: JsonSyntaxException) {
            Result.failure(e)
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 压缩 JSON 字符串
     */
    fun compact(json: String): Result<String> {
        return try {
            val jsonElement = JsonParser.parseString(json)
            Result.success(compactGson.toJson(jsonElement))
        } catch (e: JsonSyntaxException) {
            Result.failure(e)
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 验证 JSON 是否有效
     */
    fun validate(json: String): Result<Boolean> {
        return try {
            JsonParser.parseString(json)
            Result.success(true)
        } catch (e: JsonSyntaxException) {
            Result.failure(e)
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 调整缩进
     */
    private fun adjustIndent(json: String, indent: Int): String {
        if (indent == 2) return json
        
        val lines = json.lines()
        return lines.joinToString("\n") { line ->
            val leadingSpaces = line.takeWhile { it == ' ' }.length
            val newLeadingSpaces = (leadingSpaces / 2) * indent
            " ".repeat(newLeadingSpaces) + line.trimStart()
        }
    }
}

